package com.coocaa.typhoon.api.v1;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileNameUtil;
import com.coocaa.cirrus.common.base.model.RespBase;
import com.coocaa.cirrus.common.third.filestore.config.TosProperties;
import com.coocaa.typhoon.api.third.volcengine.model.video.VideoInfo;
import com.coocaa.typhoon.api.third.volcengine.service.TOSService;
import com.coocaa.typhoon.api.v1.userfile.constant.FileSceneConstant;
import com.coocaa.typhoon.api.v1.userfile.model.UploadTmpResult;
import com.coocaa.typhoon.api.v1.userfile.util.TosFinalUrlUtil;
import com.coocaa.typhoon.api.v1.userfile.util.TosUploadFilePathUtil;
import com.drew.imaging.FileType;
import com.ulisesbocchio.jasyptspringboot.EncryptablePropertyResolver;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.jasypt.encryption.StringEncryptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Arrays;
import java.util.List;


/**
 * @author bijiahao
 * @date : 2025/9/25 09:20
 * @description
 */
@Slf4j
@CrossOrigin("*")
@RestController
@RequestMapping(value = "/v1/test")
@Tag(name = "测试")
public class TestController {
    private static final String LOCAL_DIR = System.getenv("LOCAL_UPLOAD_DIR");

    @Autowired
    private TOSService tosService;
    private static final int DPI = 150;               // 清晰度，150 足够预览
    private static final Float COMPRESS_QUALITY = 0.85f;   // 图片质量 85%
    @Autowired
    private TosProperties tosProperties;
    @Autowired
    private EncryptablePropertyResolver encryptablePropertyResolver;
    @Autowired
    @Qualifier("primaryEncryptor")
    private StringEncryptor primaryEncryptor;

    @Operation(summary = "解密测试")
    @RequestMapping(value = "/testDec", method = RequestMethod.GET)
    @Parameters({
            @Parameter(name = "needDecStr", example = "ENC(cg7H0hRe3symerP4blQITw==)", description = "需要解密的字符串")
    })
    public RespBase testDec(@RequestParam String needDecStr) throws Exception {
        String dec = encryptablePropertyResolver.resolvePropertyValue(needDecStr);
        return new RespBase().setData(dec).setSuccessResult();
    }

    @Operation(summary = "加密测试")
    @RequestMapping(value = "/testEnc", method = RequestMethod.GET)
    @Parameters({
            @Parameter(name = "needEncStr", example = "test", description = "需要加密的字符串")
    })
    public RespBase testEnc(@RequestParam String needEncStr) throws Exception {
        String enc = primaryEncryptor.encrypt(needEncStr);
        return new RespBase().setData(enc).setSuccessResult();
    }

    @Operation(summary = "测试上传DOCX")
    @PostMapping(value = "/testDocx")
    public RespBase testDocx(@RequestPart("file") MultipartFile file,
                             @RequestHeader String userId
    ) throws Exception {
        String res = splitDocx(file);
        return new RespBase().setData(res).setSuccessResult();

    }

    /**
     * 调用本地 soffice 把 office 文件转成 pdf
     */
    public static void office2Pdf(File src) throws IOException, InterruptedException {
        List<String> cmd = Arrays.asList(
                "soffice",
                "--headless",
                "--convert-to", "pdf",
                "--outdir", src.getParent(),
                src.getAbsolutePath()
        );
        ProcessBuilder pb = new ProcessBuilder(cmd);
        pb.redirectErrorStream(true);
        Process p = pb.start();
        try (BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()))) {
            br.lines().forEach(System.out::println);
        }
        p.waitFor();
    }

    public String splitDocx(MultipartFile file) throws Exception {

        String ext = FileNameUtil.extName(file.getOriginalFilename());
        String fileName = TosUploadFilePathUtil.getFileName(ext);
        String localDir = LOCAL_DIR;
        if (StringUtils.isBlank(localDir)) {
            localDir = tosProperties.getTosLocalDir();
        }
        String fileLocalPath = TosUploadFilePathUtil.getLocalSaveFilePath(localDir, fileName);
        File localSaveFile = new File(fileLocalPath);
        String pdfFile = fileLocalPath.replace(ext, "pdf");
        try {
            try {
                file.transferTo(localSaveFile);
            } catch (IOException e) {
                log.error("文件转存异常", e);
                return null;
            }
            office2Pdf(localSaveFile);
            // 2. pdf -> image
            String url = "";
            try (PDDocument pdf = PDDocument.load(new File(pdfFile))) {
                PDFRenderer renderer = new PDFRenderer(pdf);
                for (int i = 0; i < pdf.getNumberOfPages(); i++) {
                    BufferedImage img = renderer.renderImageWithDPI(i, DPI); // 300 足够打印
                    // 压缩
                    ByteArrayOutputStream imgOut = new ByteArrayOutputStream();
                    String extName = FileType.Png.getName().toLowerCase();
                    Thumbnails.of(img)
                            .scale(1.0)              // 不缩放
                            .outputQuality(COMPRESS_QUALITY)
                            .outputFormat(extName)
                            .toOutputStream(imgOut);
                    String remoteUploadFilePath = TosUploadFilePathUtil.getRemoteUploadFilePathForRlsFile(tosProperties.getTosEnvDir(), fileLocalPath, i, extName, FileSceneConstant.PREVIEW);
                    tosService.uploadFile(imgOut, remoteUploadFilePath);
                    url = tosService.getFinalUrl(remoteUploadFilePath);
                    break;
                }
            }
            return url;
        } finally {
            FileUtils.deleteQuietly(localSaveFile);
            FileUtils.deleteQuietly(new File(pdfFile));
        }
    }


    @Operation(summary = "测试视频信息")
    @PostMapping(value = "/testVideoInfo")
    @Parameters({
            @Parameter(name = "tosLink", example = "tos://xxx/test/20250926_1971482178793639936.mp4", description = "视频TOS链接")
    })
    public RespBase testVideoInfo(@RequestParam String tosLink) throws Exception {
        String videoFilePath = TosFinalUrlUtil.getFilePath(tosLink);
        VideoInfo videoInfo = tosService.getVideoInfo(videoFilePath);
        return new RespBase().setData(videoInfo).setSuccessResult();
    }


    @Operation(summary = "测试视频截帧")
    @GetMapping(value = "/testVideoSnapshot")
    @Parameters({
            @Parameter(name = "tosLink", example = "tos://xxx/test/20250926_1971482178793639936.mp4", description = "视频TOS链接")
    })
    public RespBase testVideoSnapshot(@RequestParam String tosLink) throws Exception {
        String videoFilePath = TosFinalUrlUtil.getFilePath(tosLink);
        String extName = FileType.Png.getName().toLowerCase();
        String remoteUploadFilePath = TosUploadFilePathUtil.getRemoteUploadFilePathForRlsFile("test", FileUtil.getName(videoFilePath), 1, extName, FileSceneConstant.PREVIEW);
        UploadTmpResult tmpResult = tosService.videoSnapshot(videoFilePath, 1, remoteUploadFilePath, extName);
        String url = tosService.getFinalUrl(TosFinalUrlUtil.getFilePath(tmpResult.getTosLink()));
        return new RespBase().setData(url).setSuccessResult();
    }

}
